﻿using System;
using System.Collections.Generic;
using System.Text;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.DataAccess.SQLDom
{
    /// <summary>
    /// 子查询条件
    /// </summary>
    /// <remarks>动态条件</remarks>
    [Serializable]
    public class SubQueryConditionStatement : ConditionStatement
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public SubQueryConditionStatement()
            : base()
        {
            base.CreateChildCollection();
        }

        public readonly static List<RelationalOperator> ValidRelationalOperator =
            new List<RelationalOperator>
            {
                RelationalOperator.IN,
                RelationalOperator.Exists
            };

        /// <summary>
        /// 子查询条件
        /// </summary>
        public SelectSqlStatement SubQuery { get; set; }

        /// <summary>
        /// 子查询与外部查询关联关系项
        /// </summary>
        public List<SubQueryConditionItem> SubQueryConditionItems { get; set; } = new List<SubQueryConditionItem>();

        public ConditionField INClauseConditionField { get; set; }

        /// <summary>
        /// 子查询别名
        /// </summary>
        public string SubQueryAlias { get; set; }

        public override string ToSQL()
        {
            if (SubQuery == null)
                return default;
            var result = RelationalOperatorUtis.ConvertToString(RelationalOperator, DbType);
            if(!ValidRelationalOperator.Contains(RelationalOperator))
                return base.ToSQL();

            //当子查询条件声明包含条件时，将原有子查询的所有条件加入括号分组中，外部用AND连接
            string relateCondition = default;
            if (this.SubQueryConditionItems != null && this.SubQueryConditionItems.Count > 0)
            {
                if (SubQuery.FilterCondition?.ChildCollection != null && SubQuery.FilterCondition.ChildCollection.Count > 0)
                {
                    //将子查询原有条件用()包裹
                    var needWrapCondi = SubQuery.FilterCondition;
                    needWrapCondi.FieldNameWraps = FieldNameWraps;
                    SubQuery.FilterCondition = new FilterConditionStatement();
                    SubQuery.FilterCondition.ChildCollection.Add(needWrapCondi);
                }
                FilterConditionStatement newGroup = new FilterConditionStatement();
                ConditionStatement conditionStatement = new ConditionStatement();
                var joinConditionList = new List<string>();
                if (this.SubQueryConditionItems != null)
                {
                    foreach (var subQueryCondi in SubQueryConditionItems)
                    {
                        joinConditionList.Add(subQueryCondi.ToSQL());
                    }
                }
                relateCondition = string.Join(" AND ", joinConditionList);
                //newGroup.ChildCollection.Add(conditionStatement);
                ////将子查询条件声明中 【内外查询关联条件】放入新的分组，用AND连接
                //SubQuery.FilterCondition.ChildCollection.Add(newGroup);
            }
            if(RelationalOperator == RelationalOperator.Exists)
            {
                if (string.IsNullOrEmpty(relateCondition))
                    return $"EXISTS ({SubQuery.ToSQL()})";
                else //当存在与out query相关的条件时
                {
                    return $"EXISTS (select * from ({SubQuery.ToSQL()}) as {SubQueryAlias} where {relateCondition})";
                }
            }
            else if(RelationalOperator == RelationalOperator.IN)
            {
                if (FieldNameWraps != null)
                    INClauseConditionField.FieldNameWraps = FieldNameWraps;
                return $"{INClauseConditionField.ToSQL()} IN ({SubQuery.ToSQL()})";
            }
            return string.Format(result.Key, SubQuery.ToSQL());
        }
    }
}
